package ghttp

import (
	"fmt"
	"net/http"
	"net/url"
	"time"

	"gitee.com/liyp_admin/gnet/ghttp/user"

	"gitee.com/liyp_admin/gnet/gfile"
	"github.com/gorilla/mux"
	"github.com/gorilla/websocket"
)

var Handle *webST

//HttpData ...
type HttpData struct {
	Req      string
	Form     *url.Values
	ChanBack chan []byte
}

type webST struct {
	ChanAccept chan *websocket.Conn
	ChanHTTP   chan *HttpData
	httpserver *http.Server
}

func init() {
	Handle = &webST{}
	Handle.init()
}

func (v *webST) init() bool {
	v.ChanAccept = make(chan *websocket.Conn, 100)
	v.ChanHTTP = make(chan *HttpData, 100)
	v.httpserver = &http.Server{
		ReadTimeout: 3 * time.Second,
		//WriteTimeout: 5 * time.Second,
		//IdleTimeout: 3 * time.Second,
	}

	return true
}

//Close ...
func (v *webST) Close() {

}

//Start ...
func Start(port int, ssl_file string, httpIf []string) bool {
	Handle.httpserver.Addr = fmt.Sprintf(":%d", port)

	Handle.RegisterHandles(httpIf)
	go func() {
		if len(ssl_file) > 0 {
			//Log.Print("start https service")
			err := Handle.httpserver.ListenAndServeTLS(gfile.GetFilePath(fmt.Sprintf("assets/keys/%s.crt", ssl_file)), gfile.GetFilePath(fmt.Sprintf("assets/keys/%s.key", ssl_file)))
			fmt.Println(err)
			if err != nil {
				panic(err)
			}

		} else {
			//Log.Print("start http service")
			err := Handle.httpserver.ListenAndServe()
			fmt.Println(err)
			if err != nil {
				panic(err)
			}
		}

	}()

	return true
}

//RegisterHandles ...
func (v *webST) RegisterHandles(httpIf []string) {
	Route := mux.NewRouter()

	session := Route.PathPrefix("/user").Subrouter()
	session.HandleFunc("/login", user.Login)
	session.HandleFunc("/logout", user.Logout)
	session.HandleFunc("/Secret", user.Secret)

	Route.HandleFunc("/ws", v.WsPage)

	for i := 0; i < len(httpIf); i++ {
		req := httpIf[i]
		Route.HandleFunc("/"+req, v.Requst)
	}

	http.Handle("/", Route)

	fs := http.FileServer(http.Dir(gfile.GetFilePath("assets/static")))
	http.Handle("/static/", http.StripPrefix("/static/", fs))
}
func (v *webST) Requst(w http.ResponseWriter, r *http.Request) {
	// w.Header().Set("Access-Control-Allow-Origin", "*")
	origin := r.Header.Get("Origin")
	r.Header.Set("Access-Control-Allow-Origin", origin)
	r.Header.Set("Access-Control-Allow-Credentials", "true")

	defer func() {
		if err := recover(); err != nil {
			fmt.Println("回应http:失败:", err)
		}
	}()

	r.ParseForm()
	waitChan := make(chan []byte)
	v.ChanHTTP <- &HttpData{Req: r.RequestURI, Form: &r.Form, ChanBack: waitChan}

	data := <-waitChan
	if !r.Close {
		w.Header().Set("Content-Type", "application/json")
		w.Header().Set("Connection", "close")
		w.Write(data)
	} else {
		fmt.Println("Requst error! request connection is closed! when response")
	}
}

//WsPage ...
func (v *webST) WsPage(res http.ResponseWriter, req *http.Request) {
	res.Header().Set("Access-Control-Allow-Origin", "*")
	//	fmt.Println("wsPage:", req.Header)
	conn, _error := (&websocket.Upgrader{HandshakeTimeout: 3 * time.Second, CheckOrigin: func(r *http.Request) bool { return true }}).Upgrade(res, req, nil)
	if _error != nil {
		println(_error)
		http.NotFound(res, req)
		return
	}

	//\\conn.WriteMessage(websocket.TextMessage, []byte("hello world"))
	//ChanConnected <- conn
	go func() {
		v.ChanAccept <- conn
	}()

}
